package com.kaifamiao.concepts;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

public class JdkDynamicProxyTest {

    public static void main(String[] args) {
        // 代理目标
        final Object target = new ArrayList<>();
        Class<?> tc = target.getClass();
        ClassLoader loader = tc.getClassLoader();
        Class<?>[] interfaces = tc.getInterfaces();

        InvocationHandler h = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object result = null ;
                String name = method.getName();
                final boolean condition = !name.equals( "toString" );
                long begin = System.nanoTime(); // around (前半部分)
                // 对 连接点 进行筛选的条件就是 切点(pointcut)
                if( condition ) {
                    System.out.println("方法[" + name + "]执行前"); // before
                }
                try {
                    result = method.invoke(target, args); // 正在执行的方法
                    if( condition ) {
                        System.out.println("方法[" + name + "]返回: " + result); // after return
                    }
                } catch ( Throwable t ) {
                    if( condition ) {
                        System.out.println("方法[" + name + "]抛出: " + t); // after throw
                    }
                }
                if( condition ) {
                    System.out.println("方法[" + name + "]执行后"); // after
                }
                long end = System.nanoTime(); // around (后半部分)
                System.out.println( "方法[" + name + "]执行耗时 " + ( end - begin ) + "ns." ); // around (后半部分)
                return result;
            }
        };

        // 代理对象
        final Object proxy = Proxy.newProxyInstance(loader, interfaces, h );

        if( proxy instanceof List ) {
            List list = (List)proxy;
            System.out.println( list.toString() );
            list.add( "孙悟空" );
            System.out.println( list.toString() );
            list.set( 0, "唐三藏" );
            System.out.println( list.toString() );
        }

    }

}
